﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Data.Services.Client;
using TelerikStore.EbayService;
using Telerik.Web.UI;
using TelerikStore.MasterPages;
using System.Web.Services;
using System.Net;
using System.Xml.Linq;

namespace TelerikStore
{
    public partial class ProductView : System.Web.UI.Page
    {
        private static EBayData ebayContext;
        private const int AllProducts = 0;
        private double minPrice;
        private double maxPrice;
        private int condition;
        private string categoryID;
        private string searchWord;
        private static readonly String ebayString = "http://ebayodata.cloudapp.net";

        public List<ProductItem> Products
        {
            get { return (List<ProductItem>)Session["Products"]; }
            set { Session["Products"] = value; }
        }

        protected void Page_Load(object sender, EventArgs e)
        {
            if (!Page.IsPostBack)
            {
                ebayContext = new EBayData(new Uri(ebayString));
                ClearProductsFromSession();
                PopulateQueryParameters();
                string searchString = GenerateEbaySeachString();
                bool isDeal = !String.IsNullOrEmpty(Request.QueryString["Deal"]);
                GetItemsFromService(searchString, isDeal);
                PopulateInformationLabel();

                string itemId = isDeal ? Request.QueryString["Deal"] : Request.QueryString["ItemID"];

                ProductItem itemToPopulate = Products.Find(item => item.Id == itemId);

                if (itemToPopulate != null)
                {
                    int index = Products.IndexOf(itemToPopulate);
                    CurrentIndex.Value = index.ToString();
                    PopulateProductItemElements(itemToPopulate);

                    if (index == 0 && index == (Products.Count - 1))                    
                    {
                        ProductPreviousButton.Enabled = false;
                        ProductNextButton.Enabled = false;
                    }
                    else if (index == 0)
                    {
                        ProductPreviousButton.Enabled = false;
                    }
                    else if (index == (Products.Count - 1))
                    {                       
                        ProductNextButton.Enabled = false;
                    }
                }
                else
                {
                    ProductPreviousButton.Enabled = false;
                    ProductNextButton.Enabled = false;
                    BuyButton.Visible = false;
                }
            }

            string script = "(function() { $telerik.$('li',$telerik.$('nav')).removeClass('current'); }());";
            ScriptManager.RegisterStartupScript(Page, GetType(), "SetPane", script, true);

            ConfigureAjaxSettings();
        }

        //Buy button clicked.
        protected void BuyButton_Click(object sender, EventArgs e)
        {
            (Page.Master.Master as Home).AddItemToCart(Products[int.Parse(CurrentIndex.Value)]);
        }

        //Navigates to the Category View page when the search button is clicked.
        protected void PerformSearch(object sender, EventArgs e)
        {
            ClearProductsFromSession();
            Response.Redirect("./CategoryView.aspx?Search=" + SearchBox.Text);
        }

        protected void ProductPreviousButton_Click(object sender, EventArgs e)
        {
            if (Products == null)
            {
                PopulateProductItemElements(new ProductItem() { Title = "Session Ended" });
                ProductPreviousButton.Enabled = false;
                ProductNextButton.Enabled = false;
                return;
            }

            //Get the items we searched for and the current index
            List<ProductItem> searchedItems = Products;
            int itemIndex = int.Parse(CurrentIndex.Value);

            itemIndex--;

            PopulateProductItemElements(searchedItems[itemIndex]);

            ProductNextButton.Enabled = true;

            if (itemIndex == 0)
            {
                ProductPreviousButton.Enabled = false;
            }

            CurrentIndex.Value = itemIndex.ToString();
        }

        protected void ProductNextButton_Click(object sender, EventArgs e)
        {
            if (Products == null)
            {
                PopulateProductItemElements(new ProductItem() { Title = "Session Ended" });
                ProductPreviousButton.Enabled = false;
                ProductNextButton.Enabled = false;
                return;
            }

            //Get the items we searched for and the current index
            List<ProductItem> searchedItems = Products;
            int itemIndex = int.Parse(CurrentIndex.Value);

            itemIndex++;

            PopulateProductItemElements(searchedItems[itemIndex]);

            ProductPreviousButton.Enabled = true;

            if (itemIndex == (searchedItems.Count - 1))
            {
                ProductNextButton.Enabled = false;
            }

            CurrentIndex.Value = itemIndex.ToString();
        }

        //Populate all of our product-related controls
        private void PopulateProductItemElements(ProductItem itemToPopulateWith)
        {
            ProductImage.ImageUrl = itemToPopulateWith.LargePicture;
            ProductTitleLabel.Text = itemToPopulateWith.Title;
            ProductDescriptionLabel.Text = itemToPopulateWith.Description;
            ProductPriceLabel.Text = String.Format("${0}", (itemToPopulateWith.Price).ToString());
            Savings.Text = itemToPopulateWith.SavingRate != null ? string.Format("${0} Savings", itemToPopulateWith.SavingRate) : string.Empty;
        }

        private void PopulateQueryParameters()
        {
            try
            {
                minPrice = Request.QueryString["MinPrice"] != null ? double.Parse(Request.QueryString["MinPrice"]) : (double)Price.Min;
                maxPrice = Request.QueryString["MaxPrice"] != null ? double.Parse(Request.QueryString["MaxPrice"]) : (double)Price.Max;
                condition = Request.QueryString["Condition"] != null ? int.Parse(Request.QueryString["Condition"]) : AllProducts;
                categoryID = Request.QueryString["Category"] ?? string.Empty;
                searchWord = Request.QueryString["Search"] ?? string.Empty;
            }
            catch (FormatException) { }
        }

        private string GenerateEbaySeachString()
        {
            string queryString = string.Empty;

            if (!String.IsNullOrEmpty(Request.QueryString["Deal"]))
            {
                queryString = "Deals";
            }
            else
            {
                queryString = "Items?";
                if (!String.IsNullOrEmpty(searchWord))
                    queryString += String.Format("search={0}&", searchWord);

                queryString += String.Format("$filter=CurrentPrice{2}{0}{4}CurrentPrice{3}{1}", minPrice, maxPrice, EbayQueryStringsHelper.GreaterThan, EbayQueryStringsHelper.LessThan, EbayQueryStringsHelper.And);

                if (condition != AllProducts)
                    queryString += String.Format("{2}Condition/Id{1}{0}", condition, EbayQueryStringsHelper.Equal, EbayQueryStringsHelper.And);
                if (categoryID != String.Empty)
                    queryString += String.Format("{2}PrimaryCategoryId{1}{3}{0}{3}", categoryID, EbayQueryStringsHelper.Equal, EbayQueryStringsHelper.And, EbayQueryStringsHelper.Quote);
            }

            return queryString;
        }

        private void GetItemsFromService(string searchString, bool isDeal)
        {
            Products = new List<ProductItem>();
            try
            {
                Products = GetItemsFromEBay(searchString, isDeal);
            }
            catch (WebException)
            {
                ProductTitleLabel.Text = "Error with service has occured";
            }
            catch (ArgumentException)
            {
                ProductTitleLabel.Text = "Invalid Query Arguments";
            }
            catch (DataServiceClientException)
            {
                ProductTitleLabel.Text = "Error with service has occured";
            }
            catch (DataServiceQueryException)
            {
                ProductTitleLabel.Text = "Invalid Query Arguments";
            }
        }

        private List<ProductItem> GetItemsFromEBay(string searchString, bool isDeal)
        {
            List<ProductItem> items;

            if (isDeal)
                items = ebayContext.Execute<Deal>(new Uri(searchString, UriKind.Relative)).ToList().ConvertAll<ProductItem>(o => new ProductItem(o));
            else
                items = ebayContext.Execute<Item>(new Uri(searchString, UriKind.Relative)).ToList().ConvertAll<ProductItem>(o => new ProductItem(o));

            return items;
        }

        private void ConfigureAjaxSettings()
        {
            RadAjaxManager manager = RadAjaxManager.GetCurrent(Page);
            manager.AjaxRequest += new RadAjaxControl.AjaxRequestDelegate(RadAjaxManager1_AjaxRequest);
            manager.ClientEvents.OnResponseEnd = "onRespondEnd";
            manager.AjaxSettings.AddAjaxSetting(BuyButton, Page.Master.Master.FindControl("CartRotator"));
            manager.AjaxSettings.AddAjaxSetting(BuyButton, Page.Master.Master.FindControl("ItemsTotalLabel"));
            manager.AjaxSettings.AddAjaxSetting(BuyButton, Page.Master.Master.FindControl("PriceTotalLabel"));
        }

        //Redirects to the Category View page when an items from the menu is clicked.
        protected void RadAjaxManager1_AjaxRequest(object sender, AjaxRequestEventArgs e)
        {
            ClearProductsFromSession();
            String[] arguments = e.Argument.Split(",".ToCharArray());
            if (arguments[0] == "Category")
            {
                Response.RedirectLocation = "./CategoryView.aspx?Category=" + arguments[1];
            }
        }

        private void ClearProductsFromSession()
        {
            Session.Remove("Products");
        }

        private void PopulateInformationLabel()
        {
            if (!String.IsNullOrEmpty(categoryID))
            {
                string categoriesPath = "~/CategoryList.xml";
                var physPath = HttpContext.Current.Server.MapPath(categoriesPath);

                var result = XDocument.Load(physPath).Element("Menu")
                    .Element("Group")
                    .Elements("Item")
                    .Single(x => x.Attribute("Value").Value == categoryID);

                InformationLabel.Text = result.Attribute("Text").Value;
            }
            else if (!String.IsNullOrEmpty(searchWord))
            {
                InformationLabel.Text = "Search Results";
            }
            else if (!String.IsNullOrEmpty(Request.QueryString["Deal"]))
            {
                InformationLabel.Text = "Deals of the day";
            }
        }

        //Returns the title of the previous or next item in the list.
        [WebMethod]
        public static string GetNextOrPrevious(Boolean isNext, int index)
        {

            if (HttpContext.Current.Session["Products"] == null)
            {
                return string.Empty;
            }

            List<ProductItem> searchedItems = HttpContext.Current.Session["Products"] as List<ProductItem>;

            if (isNext)
            {
                return searchedItems[index + 1].Title.ToString();
            }
            else
            {
                return searchedItems[index - 1].Title.ToString();
            }
        }

    }
}
